package com.liannong.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liannong.entity.Product;
import com.liannong.mapper.ProductMapper;
import com.liannong.service.ProductService;
import com.liannong.service.WarehouseService;
import com.liannong.service.BlockchainService;
import com.liannong.vo.ProductVO;
import com.liannong.exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    private final WarehouseService warehouseService;
    private final BlockchainService blockchainService;
    private final StringRedisTemplate redisTemplate;

    @Autowired
    public ProductServiceImpl(WarehouseService warehouseService, 
                            BlockchainService blockchainService,
                            StringRedisTemplate redisTemplate) {
        this.warehouseService = warehouseService;
        this.blockchainService = blockchainService;
        this.redisTemplate = redisTemplate;
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public List<ProductVO> getProductList() {
        log.info("开始查询产品列表");
        List<Product> products = this.list();
        log.info("查询到产品数量: {}", products.size());
        
        if (products.isEmpty()) {
            log.warn("没有查询到产品数据");
            return Collections.emptyList();
        }
        
        // 打印第一个产品的信息用于调试
        Product firstProduct = products.get(0);
        log.info("第一个产品信息: id={}, name={}, price={}", 
                firstProduct.getProductId(), 
                firstProduct.getName(), 
                firstProduct.getPrice());
        
        List<ProductVO> result = products.stream()
                .map(this::convertToProductVO)
                .collect(Collectors.toList());
        log.info("转换后的产品VO数量: {}", result.size());
        return result;
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public ProductVO getProductDetail(Long productId) {
        Product product = this.getById(productId);
        if (product == null) {
            return null;
        }
        return convertToProductVO(product);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStock(Long productId, Integer stock) {
        Product product = this.getById(productId);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }

        // 更新仓库库存
        try {
            warehouseService.updateWarehouseAmount(productId, stock);
            return true;
        } catch (Exception e) {
            log.error("更新仓库库存失败", e);
            return false;
        }
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public List<ProductVO> getProductsByTemperature(Integer minTemp, Integer maxTemp) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("min_temp", minTemp)
                   .le("max_temp", maxTemp);
        List<Product> products = this.list(queryWrapper);
        return products.stream()
                .map(this::convertToProductVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(Product product) {
        return super.updateById(product);
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public Long getProductIdByTraceCode(String traceCode) {
        if (traceCode == null || traceCode.trim().isEmpty()) {
            log.warn("溯源码为空");
            return null;
        }
        
        log.info("根据溯源码查询商品: {}", traceCode);
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("traceCode", traceCode);
        Product product = this.getOne(queryWrapper);
        
        if (product != null && product.getProductId() != null) {
            log.info("找到商品: id={}, name={}", product.getProductId(), product.getName());
            return product.getProductId().longValue();
        } else {
            log.warn("未找到溯源码对应的商品: {}", traceCode);
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addProductByFarmer(Product product, Integer userId) {
        if (product == null || userId == null) {
            log.error("商品信息或用户ID为空");
            return false;
        }
        
        log.info("果农添加商品 - userId: {}, productName: {}", userId, product.getName());
        
        // 生成溯源码 (使用时间戳+随机数)
        String traceCode = generateTraceCode();
        product.setTraceCode(traceCode);
        
        // 设置商品的创建者和审核状态
        product.setCreateUserId(userId);
        product.setAuditStatus(0); // 待审核
        
        // 保存商品信息
        boolean result = this.save(product);
        if (result) {
            log.info("果农添加商品成功 - productId: {}, traceCode: {}", product.getProductId(), traceCode);
            
            // 提交到区块链
            try {
                submitToBlockchain(product);
                log.info("商品信息已提交到区块链 - productId: {}, traceCode: {}", product.getProductId(), traceCode);
            } catch (Exception e) {
                log.error("提交商品信息到区块链失败", e);
                // 区块链提交失败不影响主流程
            }
        } else {
            log.error("果农添加商品失败");
        }
        return result;
    }
    
    /**
     * 生成溯源码
     * 格式：时间戳(10位) + 4位随机数
     */
    private String generateTraceCode() {
        long timestamp = System.currentTimeMillis() / 1000; // 10位时间戳
        int random = (int)(Math.random() * 10000); // 4位随机数
        return String.format("%d%04d", timestamp, random);
    }
    
    /**
     * 提交商品信息到区块链
     */
    private void submitToBlockchain(Product product) {
        boolean success = blockchainService.createQualityRecord(product);
        if (!success) {
            log.warn("商品信息提交到区块链失败 - productId: {}, traceCode: {}", 
                product.getProductId(), product.getTraceCode());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditProduct(Integer productId, Integer auditUserId, Integer auditStatus, String auditComment) {
        if (productId == null || auditUserId == null || auditStatus == null) {
            log.error("审核参数不完整");
            return false;
        }
        
        // 检查Redis中是否存在审核记录
        String auditKey = "product:audit:" + productId;
        String existingAudit = redisTemplate.opsForValue().get(auditKey);
        if (existingAudit != null) {
            log.warn("商品已被审核 - productId: {}", productId);
            return false;
        }
        
        log.info("管理员审核商品 - productId: {}, auditUserId: {}, auditStatus: {}", 
                productId, auditUserId, auditStatus);
        
        // 使用数据库锁查询商品信息
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", productId)
                   .last("FOR UPDATE");  // 添加行锁
        Product product = this.getOne(queryWrapper);
        
        if (product == null) {
            log.error("商品不存在 - productId: {}", productId);
            return false;
        }
        
        // 检查商品是否待审核状态
        if (product.getAuditStatus() != 0) {
            log.warn("商品不是待审核状态 - productId: {}, currentStatus: {}", 
                    productId, product.getAuditStatus());
            return false;
        }
        
        // 更新审核信息
        product.setAuditStatus(auditStatus);
        product.setAuditUserId(auditUserId);
        product.setAuditTime(LocalDateTime.now());
        product.setAuditComment(auditComment);
        
        // 保存审核结果
        boolean result = this.updateById(product);
        if (result) {
            // 在Redis中记录审核状态，设置24小时过期
            redisTemplate.opsForValue().set(auditKey, String.valueOf(auditStatus), 24, TimeUnit.HOURS);
            
            log.info("商品审核成功 - productId: {}, auditStatus: {}", productId, auditStatus);
            
            // 如果审核通过，将产品信息提交到区块链
            if (auditStatus == 1) {
                try {
                    boolean blockchainResult = blockchainService.createQualityRecord(product);
                    if (blockchainResult) {
                        log.info("商品信息成功提交到区块链 - productId: {}", productId);
                    } else {
                        log.warn("商品信息提交到区块链失败 - productId: {}", productId);
                    }
                } catch (Exception e) {
                    log.error("提交商品信息到区块链时发生错误 - productId: " + productId, e);
                }
            }
        } else {
            log.error("商品审核失败 - productId: {}", productId);
        }
        return result;
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public List<ProductVO> getPendingAuditProducts() {
        log.info("查询待审核商品列表");
        
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("audit_status", 0); // 待审核状态
        
        List<Product> products = this.list(queryWrapper);
        log.info("查询到待审核商品数量: {}", products.size());
        
        return products.stream()
                .map(this::convertToProductVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public List<ProductVO> getProductsByFarmer(Integer farmerId) {
        if (farmerId == null) {
            log.error("果农ID为空");
            return Collections.emptyList();
        }
        
        log.info("查询果农创建的商品列表 - farmerId: {}", farmerId);
        
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("create_user_id", farmerId);
        
        List<Product> products = this.list(queryWrapper);
        log.info("查询到果农创建的商品数量: {}", products.size());
        
        return products.stream()
                .map(this::convertToProductVO)
                .collect(Collectors.toList());
    }

    private ProductVO convertToProductVO(Product product) {
        if (product == null) {
            log.warn("尝试转换空的Product对象");
            return null;
        }
        
        ProductVO productVO = new ProductVO();
        BeanUtils.copyProperties(product, productVO);
        productVO.setProductName(product.getName());  // 设置前端展示用的名称
        
        // 确保productId被正确设置（处理Integer到Long的转换）
        if (product.getProductId() != null) {
            productVO.setProductId(product.getProductId().longValue());
            log.info("设置productId: {} -> {}", product.getProductId(), productVO.getProductId());
        } else {
            log.warn("产品ID为空: {}", product.getTraceCode());
        }
        
        // 添加审核状态信息
        if (product.getAuditStatus() != null) {
            productVO.setAuditStatus(product.getAuditStatus());
            productVO.setAuditStatusText(getAuditStatusText(product.getAuditStatus()));
        }
        
        log.debug("转换后的ProductVO: id={}, name={}", productVO.getProductId(), productVO.getProductName());
        return productVO;
    }
    
    /**
     * 获取审核状态文本
     * @param status 审核状态码
     * @return 状态文本
     */
    private String getAuditStatusText(Integer status) {
        if (status == null) {
            return "未知状态";
        }
        
        switch (status) {
            case 0:
                return "待审核";
            case 1:
                return "审核通过";
            case 2:
                return "审核拒绝";
            default:
                return "未知状态";
        }
    }
} 